package org.binglan.youziyuepai.controller;

import io.swagger.annotations.*;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.binglan.youziyuepai.config.WxAccountConfig;
import org.binglan.youziyuepai.controller.base.BasicController;
import org.binglan.youziyuepai.entity.Image;
import org.binglan.youziyuepai.entity.User;
import org.binglan.youziyuepai.entity.bo.AuthCode2Session;
import org.binglan.youziyuepai.entity.bo.WxUserInfo;
import org.binglan.youziyuepai.enums.ResponseEnum;
import org.binglan.youziyuepai.form.WxLoginForm;
import org.binglan.youziyuepai.service.ImageService;
import org.binglan.youziyuepai.service.UserService;
import org.binglan.youziyuepai.utils.*;
import org.binglan.youziyuepai.vo.ResponseVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * @description: 登陆相关 controller
 * @author: sanjin
 * @date: 2019/4/9 12:20
 */

@Api(tags = "登陆/注册/登出相关业务")
@RestController
public class LoginController extends BasicController {

    @Autowired
    UserService userService;

    @Autowired
    ImageService imageService;

    @ApiOperation(value = "小程序登陆注册接口", notes = "该接口返回 token")
    @PostMapping("/wxlogin")
    public ResponseVo login(@Valid @RequestBody WxLoginForm wxLoginForm,
                            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseVoUtils.error(bindingResult);
        }

        // 小程序登陆
        // auth.code2Session 地址
        String url = String.format(
                " https://api.weixin.qq.com/sns/jscode2session?" +
                        "appid=%s&" + // appid
                        "secret=%s&" + // secret
                        "js_code=%s&" + // code
                        "grant_type=authorization_code",
                WxAccountConfig.APPID, WxAccountConfig.SECRET, wxLoginForm.getCode()
        );

        String jsonData = OkHttpUtils.doGet(url);
        AuthCode2Session authCode2Session = JsonUtils.jsonToPojo(jsonData, AuthCode2Session.class);
        // 验证 auth.code2Session 请求是否发送成功，0 表示成功，详见小程序官方文档
        if (authCode2Session == null || authCode2Session.getErrcode() != 0) {
            return ResponseVoUtils.error("服务端请求 auth.code2Session 接口错误");
        }
        // 根据  openid 判断该用户是否存在
        User queryUser = userService.queryUserByOpenid(authCode2Session.getOpenid());

        String jwtToken = "";

        if (queryUser != null) {
            // 用户存在，通过 id，openid 生成 jwtToken
            User user = userService.queryUserByOpenid(authCode2Session.getOpenid());
            jwtToken = JwtUtils.sign(user.getId(), user.getOpenid());
        } else {
            // 进行微信开放信息的 signature 验证
            String plaintext = wxLoginForm.getRawData() + authCode2Session.getSession_key();
            // sha1 加密
            String ciphertext = EncryptUtils.sha1(plaintext);
            if (!ciphertext.equals(wxLoginForm.getSignature())) {
                return ResponseVoUtils.error("signature 不正确，用户微信开放信息错误");
            }
            // 用户不存在，进行保存
            // 从表单获取用户数据 nickname,gender,language,city,province,country,avatarUrl,
            WxUserInfo wxUserInfo = JsonUtils.jsonToPojo(wxLoginForm.getRawData(), WxUserInfo.class);
            if (wxUserInfo == null) {
                return ResponseVoUtils.error("rawData 错误,用户信息不能为空");
            }
            User user = new User();
            Image avatar = new Image();
            avatar.setUrl(wxUserInfo.getAvatarUrl());
            Image saveImage = imageService.saveImage(avatar);



            BeanUtils.copyProperties(wxUserInfo, user);
            user.setOpenid(authCode2Session.getOpenid());           // openid
            user.setSessionKey(authCode2Session.getSession_key());  // session_key
            user.setSignature("这个人很懒,什么都没有~~");             // signature
            user.setSchoolId(1);                                    // 学校 id,默认1 其他
            user.setBonusPoints(0);                                 // 初始积分
            user.setImageId(saveImage.getId());
            User saveUser = userService.saveUser(user);
            // 通过 id，openid 生成 jwtToken
            jwtToken = JwtUtils.sign(saveUser.getId(), saveUser.getOpenid());
        }
        return ResponseVoUtils.success(jwtToken);
    }



    @ApiOperation(value = "用户登出接口",notes = "用户登出接口")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "认证 token", required = true, paramType = "header", dataType = "string")
    )
    @PostMapping("/logout")
    public ResponseVo logout() {

        Subject subject = this.getSubjectByAuth();
        subject.logout();
        //TODO 删除缓存
        return ResponseVoUtils.success();
    }

}
